//
//  IAP.h
//  Source
//
//  Created by Toj on 5/9/22.
//
//  内购

iOS内购是指 苹果应用程序 在购买某个虚拟物品通过iOS系统支付渠道方式购买(非其他支付渠道)，即In-App Purchase，简称IAP

App Store审核指南规定:
1. 如果您想要在 app 内解锁特性或功能, 则必须使用 App 内购买项目.
(例如: 订阅、游戏币、游戏关卡、优质内容的访问限或解锁完整版VIP会员等)
2. App 不得使用自身机制来解锁内容或功能,
(例如: 许可证密钥、增强现实标记、二维码等)
3. App 及其元数据不得包含按钮、外部链接或其他行动号召用语, 以指引用户使用非 App 内购买项目机制进行购买

*** 总结
* 就是app 内虚拟物品跟钱挂钩 iOS必须通过内购方式购买支付, 不允许第三方支付平台(包括支付宝, 微信,Apple pay等)
* 其实也不是绝对, 比如课程其实可以通过其他平台购买, 其他平台不是某个app哈, app不牵扯引导使用者在外购买的信息即可.
比如电脑网站内, 或者线下购买, 在app 内展示课程/ 上课而已

IAP 是一套商品交易系统, 而非简单的支付系统, 每一个购买项目都需要在开发者后台的Itunes Connect后台为 App 创建一个对应的商品, 提交给苹果审核通过后, 购买项目才会生效.

准备工作:
1. 填写协议, 税务和银行业务. 详细看【IAPAgreements.h】
2. 内购流程. 详细看【IAPProduct.h】
3. 沙盒测试员. 详细看【IAPAppIDAccount.h】
*** 填写银行账户信息一般交由产品管理人员负责, 开发者不需要关注, 开发者需要关注的是第二步和第三步
*** 如果税务 协议有更新苹果会通知你, 每次提包需要先更新协议后才可以提新包否则无法操作

#pragma mark - IAP的支付流程
支付流程: IAPPayProcess.swift

1，发起支付
2，扣费成功
3，得到receipt（支付凭据）
4，去后台验证凭据获取商品交易状态
5，返回数据，验证成功前端刷新数据

#pragma mark - IAP的支付流程
漏单情况一:
2到3环节出问题
属于苹果的问题, 目前没做处理.

漏单情况二:
3到4的时候出问题, 比如断网.
此时前端会把支付凭据持久化存储下来, 如果期间用户卸载APP此单在前端就真漏了, 如果没有卸载,
下次重新打开app进入购买页会先判断有无未成功的支付, 有就提示用户, 用户选择找回, 重走4，5流程.
这一步看产品需求怎么做, 可以让用户自主选择是否恢复未成功的支付也可以前端默默恢复就行.

漏单情况三:
4到5的时候出问题.
此时后台其实已经成功, 只是前端没获取到数据, 当漏单处理,下次进入的时候先刷新数据即可.

漏单情况四:
2后, 用户更换了 APP ID, 导致 keychain 被更改.

漏单情况五:
2后, 此时用户更换了手机, 那么此时收据肯定是拿不到的.

***
漏单情况六:
越狱设备内购盗刷行为, 不建议对越狱设备开放内购行为

#pragma mark - 交易凭证持久化

KeychainSwift
1. 当 APP 和服务器通讯, 等待服务器去苹果服务器查询收据真伪时可能出现失败, 而苹果只在每次 APP 启动的时候才触发一次事务查询代理, 所以必须自己实现一套查询收据查询机制.
2. 当交易状态变为 SKPaymentTransactionStatePurchased(支付完成) 时, 就会将交易数据持久化到 keychain.
3. 持久化以后, 由重试查询收据队列触发服务器向苹果服务器进行收据有效性查询, 并且根据后台返回的结果对交易凭证对象状态进行更新(finish 掉).
4. 当查询收据有效以后, 将从 keychain 里移除掉对应的交易模型数据.
5. 当查询收据有效无效, 将从 keychain 里移除掉对应的交易模型数据.
